################################################################################
# CS 240 Chess Project Makefile
# 
# Last Modified: 22 March 2011 by Jacob Austin 
#
# INSTRUCTIONS: This is a starting makefile for the chess project. You are to 
# keep this up-to-date as you add source files. In addition to keeping it 
# up-to-date with new files you create, you need to make the following changes 
# to this makefile:
# 
#	- compile the object files associated with the View into a shared library, 
#	- add pseudo-targets for the different run modes (namely "runhh", "runhc",
#		"runch", and "runcc"),
#	- add a "test" pseudo-target (you will probably want to make a new executable
#		for this with its own main method),
#	- add a "lib" pseudo-target,
#	- edit the command associated with the memcheck pseudo-target (i.e.,
#		the valgrind command. See the note above it for details).
# 
# NOTES: 
# 1. All the code for the GUI side of this project is provided for you. As a 
# result, there are some things in this makefile which you do not need to alter.
# Such items will be clearly marked with comments.
# 2. Out-of-the-box, without making any changes to this initial makefile, 
# running "make run" will compile the code and bring up an empty GUI. 
################################################################################

 
############### --- BEGIN UNTOUCHABLE SECTION - Do Not Edit --- ################
# Macros for GUI libraries.
GTKMM = gtkmm-2.4
SIGC = sigc++-2.0
LIBGLADE = libglademm-2.4

# TODO Re-phrase: CFLAGS are the -I values needed to compile files using the 
# GTKMM, SIGC, and LIBGLADE libraries
CFLAGS = `pkg-config $(GTKMM) $(SIGC) $(LIBGLADE) --cflags`
LIBS   = `pkg-config $(GTKMM) $(SIGC) $(LIBGLADE) --libs`
####################### --- END UNTOUCHABLE SECTION --- ########################


# TODO Re-phrase: Macros for directory tree locations
MODEL_SRC = model/src/
MODEL_INC = model/inc/
MODEL_OBJ = model/obj/
VIEW_SRC = view/src/
VIEW_INC = view/inc/
VIEW_OBJ = view/obj/
CONT_SRC = controller/src/
CONT_INC = controller/inc/
CONT_OBJ = controller/obj/

# normal executable
EXE = bin/chess

# executable for memory testing
MEXE = bin/mchess

# executable for unit testing
UEXE = bin/uchess

# Macros for compilation flags
INCLUDES = -I$(MODEL_INC) -I$(VIEW_INC) -I$(CONT_INC) -Iutil/inc
DEBUG = -g # Uncomment this if you want to compile with debug info
LINK = -Llib -lboost_regex -lcs240utils


# There are three different main.o files. One is for memory testing and one is for unit testing.
MAIN_O = $(CONT_OBJ)main.o
MEMMAIN_O = $(CONT_OBJ)memcheck_main.o
UTESTMAIN_O = $(CONT_OBJ)utest_main.o

# This macro should be used to store all of the object files created 
# from *your* source files
MY_OBJS = $(MODEL_OBJ)Piece.o \
      $(MODEL_OBJ)Pawn.o \
      $(MODEL_OBJ)Rook.o \
      $(MODEL_OBJ)Knight.o \
      $(MODEL_OBJ)Bishop.o \
      $(MODEL_OBJ)Queen.o \
      $(MODEL_OBJ)King.o \
      $(MODEL_OBJ)Board.o \
      $(MODEL_OBJ)Location.o \
      $(MODEL_OBJ)Move.o \
      $(CONT_OBJ)ChessXMLParser.o \
      $(CONT_OBJ)ChessController.o \
      $(MODEL_OBJ)Game.o \
      $(CONT_OBJ)ChessPlayer.o \
      $(CONT_OBJ)HumanPlayer.o \
      $(CONT_OBJ)ComputerPlayer.o \
      $(CONT_OBJ)ChessXMLGenerator.o

# These are all the object files that go into the library
LIB_OBJS = $(VIEW_OBJ)ChessView.o \
      $(VIEW_OBJ)ChessGuiBoardCell.o \
      $(VIEW_OBJ)ChessGuiBoard.o \
      $(VIEW_OBJ)ChessGui.o \
      $(VIEW_OBJ)ChessGuiImages.o \
      $(VIEW_OBJ)SelectDialog.o


################################################################################
# Pseudo-targets

runhh: $(EXE)
	export LD_LIBRARY_PATH=${PWD}/lib ; $(EXE) 0

runhc: $(EXE)
	export LD_LIBRARY_PATH=${PWD}/lib ; $(EXE) 1

runch: $(EXE)
	export LD_LIBRARY_PATH=${PWD}/lib ; $(EXE) 2

runcc: $(EXE)
	export LD_LIBRARY_PATH=${PWD}/lib ; $(EXE) 3

bin: $(EXE)

lib : $(LIB_OBJS)
	g++ -shared -o lib/libcs240utils.so $(LIB_OBJS)

# Run the executable for memory testing
# Instructions: Uncomment and edit the command below so that it runs the  
# memory-check executable in Human-Human mode (i.e., add necessary command  
# line arguments to the end of valgrind the command below).	
memcheck: $(MEXE)
	export LD_LIBRARY_PATH=${PWD}/lib ; valgrind --tool=memcheck --leak-check=yes --max-stackframe=5000000 --show-reachable=yes --suppressions=string.supp $(MEXE) 0#command-line args go here

# Run the unit tests
test: $(UEXE)
	export LD_LIBRARY_PATH=${PWD}/lib ; $(UEXE) 0

style: bin
	../../CppCheckStyle/CppCheckStyle model/src/*.cpp controller/src/*.cpp

testall: test memcheck style

# Clean removes all of the .o files, libraries, and executables
clean:
	@rm -f $(MODEL_OBJ)*.o
	@rm -f $(VIEW_OBJ)*.o
	@rm -f $(CONT_OBJ)*.o
	@rm -f $(EXE)
	@rm -f $(MEXE)
	@rm -f $(UEXE)


################################################################################
# Targets for executables and main object files

# Explanation: There are two different executables, with two different main 
# object files, because main.cpp needs to be built differently depending on 
# whether you are doing memory testing or not. This is because the GTK library,
# and other GUI tools, have memory leaks that we cannot figure out how to 
# suppress. Therefore, when building an executable for memory testing, we use a
# macro (MEMCHECK) to tell the compiler to not include the code that builds the
# GUI. So when we check for memory leaks during passoff, we don't have to use
# the GUI.

# Main executable
# Note: Once you have added the ability to make a library out of the View files, 
# the executable should be dependant on, and link in the library file, not the 
# .o files! That means, instead of linking in $(LIB_OBJS) below, you should link
# in the actual library file.
$(EXE): $(MAIN_O) $(MY_OBJS) lib
	@# Re-link executable. Again, this should link the library file, not the .o's
	g++ $(INCLUDES) $(CFLAGS) $(LIBS) -o $(EXE) $(MAIN_O) $(MY_OBJS) $(LINK)

	chmod ugo+x $(EXE)

# Executable for memory testing
$(MEXE): $(MEMMAIN_O) $(MY_OBJS) lib
	@# Re-link executable. Again, this should link the library file, not the .o's
	g++ $(INCLUDES) $(CFLAGS) $(LIBS) -o $(MEXE) $(MEMMAIN_O) $(MY_OBJS) $(LINK)
	chmod ugo+x $(MEXE)

# Executable for unit testing
$(UEXE): $(UTESTMAIN_O) $(MY_OBJS) lib
	@# Re-link executable. Again, this should link the library file, not the .o's
	g++ $(INCLUDES) $(CFLAGS) $(LIBS) -o $(UEXE) $(UTESTMAIN_O) $(MY_OBJS) $(LINK)
	chmod ugo+x $(UEXE)

# Main object file
$(MAIN_O): $(CONT_SRC)main.cpp $(VIEW_INC)ChessGuiImages.h $(VIEW_INC)ChessView.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(MAIN_O) -c $(CONT_SRC)main.cpp

# Main .o for memory testing
$(MEMMAIN_O): $(CONT_SRC)main.cpp $(VIEW_INC)ChessGuiImages.h $(VIEW_INC)ChessView.h
	g++ -DMEMCHECK $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(MEMMAIN_O) -c $(CONT_SRC)main.cpp

# Main .o for unit testing
$(UTESTMAIN_O): $(CONT_SRC)main.cpp $(VIEW_INC)ChessGuiImages.h $(VIEW_INC)ChessView.h
	g++ -DUTEST $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(UTESTMAIN_O) -c $(CONT_SRC)main.cpp


################################################################################
# Targets for YOUR object files...

$(MODEL_OBJ)Piece.o : $(MODEL_SRC)Piece.cpp $(MODEL_INC)Piece.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(MODEL_OBJ)Piece.o -c $(MODEL_SRC)Piece.cpp

$(MODEL_OBJ)Pawn.o : $(MODEL_SRC)Pawn.cpp $(MODEL_INC)Pawn.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(MODEL_OBJ)Pawn.o -c $(MODEL_SRC)Pawn.cpp

$(MODEL_OBJ)Rook.o : $(MODEL_SRC)Rook.cpp $(MODEL_INC)Rook.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(MODEL_OBJ)Rook.o -c $(MODEL_SRC)Rook.cpp

$(MODEL_OBJ)Knight.o : $(MODEL_SRC)Knight.cpp $(MODEL_INC)Knight.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(MODEL_OBJ)Knight.o -c $(MODEL_SRC)Knight.cpp

$(MODEL_OBJ)Bishop.o : $(MODEL_SRC)Bishop.cpp $(MODEL_INC)Bishop.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(MODEL_OBJ)Bishop.o -c $(MODEL_SRC)Bishop.cpp

$(MODEL_OBJ)Queen.o : $(MODEL_SRC)Queen.cpp $(MODEL_INC)Queen.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(MODEL_OBJ)Queen.o -c $(MODEL_SRC)Queen.cpp

$(MODEL_OBJ)King.o : $(MODEL_SRC)King.cpp $(MODEL_INC)King.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(MODEL_OBJ)King.o -c $(MODEL_SRC)King.cpp

$(MODEL_OBJ)Board.o : $(MODEL_SRC)Board.cpp $(MODEL_INC)Board.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(MODEL_OBJ)Board.o -c $(MODEL_SRC)Board.cpp

$(MODEL_OBJ)Location.o : $(MODEL_SRC)Location.cpp $(MODEL_INC)Location.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(MODEL_OBJ)Location.o -c $(MODEL_SRC)Location.cpp

$(MODEL_OBJ)Move.o : $(MODEL_SRC)Move.cpp $(MODEL_INC)Move.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(MODEL_OBJ)Move.o -c $(MODEL_SRC)Move.cpp

$(MODEL_OBJ)Game.o : $(MODEL_SRC)Game.cpp $(MODEL_INC)Game.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(MODEL_OBJ)Game.o -c $(MODEL_SRC)Game.cpp

$(CONT_OBJ)ChessXMLParser.o : $(CONT_SRC)ChessXMLParser.cpp $(CONT_INC)ChessXMLParser.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(CONT_OBJ)ChessXMLParser.o -c $(CONT_SRC)ChessXMLParser.cpp

$(CONT_OBJ)ChessController.o : $(CONT_SRC)ChessController.cpp $(CONT_INC)ChessController.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(CONT_OBJ)ChessController.o -c $(CONT_SRC)ChessController.cpp

$(CONT_OBJ)ChessPlayer.o : $(CONT_SRC)ChessPlayer.cpp $(CONT_INC)ChessPlayer.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(CONT_OBJ)ChessPlayer.o -c $(CONT_SRC)ChessPlayer.cpp

$(CONT_OBJ)HumanPlayer.o : $(CONT_SRC)HumanPlayer.cpp $(CONT_INC)HumanPlayer.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(CONT_OBJ)HumanPlayer.o -c $(CONT_SRC)HumanPlayer.cpp

$(CONT_OBJ)ComputerPlayer.o : $(CONT_SRC)ComputerPlayer.cpp $(CONT_INC)ComputerPlayer.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(CONT_OBJ)ComputerPlayer.o -c $(CONT_SRC)ComputerPlayer.cpp

$(CONT_OBJ)ChessXMLGenerator.o : $(CONT_SRC)ChessXMLGenerator.cpp $(CONT_INC)ChessXMLGenerator.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(CONT_OBJ)ChessXMLGenerator.o -c $(CONT_SRC)ChessXMLGenerator.cpp




################################################################################
# Targets for GUI-related object files
# Instructions: These will have to be recompiled as position-independant code, 
# so that they can be put into a shared library.

$(VIEW_OBJ)ChessView.o: $(VIEW_SRC)ChessView.cpp $(VIEW_INC)SelectDialog.h $(VIEW_INC)ChessView.h $(CONT_INC)IChessController.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(VIEW_OBJ)ChessView.o -c -fPIC $(VIEW_SRC)ChessView.cpp

$(VIEW_OBJ)ChessGuiBoardCell.o: $(VIEW_SRC)ChessGuiBoardCell.cpp $(VIEW_INC)ChessGuiBoardCell.h $(VIEW_INC)ChessGuiImages.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(VIEW_OBJ)ChessGuiBoardCell.o -c -fPIC $(VIEW_SRC)ChessGuiBoardCell.cpp

$(VIEW_OBJ)ChessGuiBoard.o: $(VIEW_SRC)ChessGuiBoard.cpp $(VIEW_INC)ChessGuiBoard.h $(VIEW_INC)ChessGui.h $(VIEW_INC)ChessGuiImages.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(VIEW_OBJ)ChessGuiBoard.o -c -fPIC $(VIEW_SRC)ChessGuiBoard.cpp

$(VIEW_OBJ)ChessGui.o: $(VIEW_SRC)ChessGui.cpp $(VIEW_INC)ChessGui.h $(VIEW_INC)ChessGuiImages.h $(VIEW_INC)SelectDialog.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(VIEW_OBJ)ChessGui.o -c -fPIC $(VIEW_SRC)ChessGui.cpp

$(VIEW_OBJ)ChessGuiImages.o: $(VIEW_SRC)ChessGuiImages.cpp $(VIEW_INC)ChessGuiImages.h $(VIEW_INC)Inline.h
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(VIEW_OBJ)ChessGuiImages.o -c -fPIC $(VIEW_SRC)ChessGuiImages.cpp

$(VIEW_OBJ)SelectDialog.o: $(VIEW_SRC)SelectDialog.cpp
	g++ $(DEBUG) $(INCLUDES) $(CFLAGS) $(LIBS) -o $(VIEW_OBJ)SelectDialog.o -c -fPIC $(VIEW_SRC)SelectDialog.cpp

